package com.amit.Contollers;

import com.amit.client.domain.LectureVO;
import com.amit.client.domain.StudentVO;
import com.amit.entities.LectureEntity;
import com.amit.services.LectureService;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.codehaus.jackson.map.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

@SuppressWarnings("UnusedDeclaration")
@Controller
@RequestMapping(value = "/lecture")
public final class LectureController {

    private Logger logger = Logger.getLogger(this.getClass());

    private ObjectMapper mapper;

    @Autowired
    private LectureService service;

    public LectureController() {
        mapper = new ObjectMapper();
    }

    @RequestMapping(method = RequestMethod.POST)
    @ResponseBody
    public ResponseEntity<String> addLecture(@RequestBody LectureVO lectureVO) {
        if (lectureVO == null || StringUtils.isEmpty(lectureVO.getName())) {
            logger.error("lecture name can't be empty");
            return new ResponseEntity<>("lecture name can't be empty", HttpStatus.BAD_REQUEST);
        }
        return new ResponseEntity<>(service.addLecture(lectureVO.getName()).toString(), HttpStatus.CREATED);
    }

    @RequestMapping(value = "/{lectureId}", method = RequestMethod.DELETE)
    @ResponseBody
    public ResponseEntity<String> removeLecture(@PathVariable("lectureId") Long lectureId) {
        if (lectureId == null) {
            logger.error("lecture id can't be empty");
            return new ResponseEntity<>("lecture id can't be empty", HttpStatus.BAD_REQUEST);
        }
        service.removeLecture(lectureId);
        return new ResponseEntity<>(HttpStatus.OK);
    }

    @RequestMapping(value = "/{lectureId}", method = RequestMethod.POST)
    @ResponseBody
    public ResponseEntity<String> addStudentToLecture(@PathVariable("lectureId") Long lectureId, @RequestBody StudentVO student) {
        if (lectureId == null || student == null || student.getId() == null) {
            logger.error("lecture id or studentId can't be empty");
            return new ResponseEntity<>("lectureId or studentId can't be empty", HttpStatus.BAD_REQUEST);
        }
        service.addStudentToLecture(student.getId(), lectureId);
        return new ResponseEntity<>(HttpStatus.CREATED);
    }

    @RequestMapping(value = "/{lectureId}/{studentId}", method = RequestMethod.DELETE)
    @ResponseBody
    public ResponseEntity<String> removeStudentFromLecture(@PathVariable("lectureId") Long lectureId, @PathVariable("studentId") Long studentId) {
        if (lectureId == null | studentId == null) {
            logger.error("lecture id or studentId can't be empty");
            return new ResponseEntity<>("lectureId or studentId can't be empty", HttpStatus.BAD_REQUEST);
        }
        service.removeStudentFromLecture(studentId, lectureId);
        return new ResponseEntity<>(HttpStatus.OK);
    }


    @RequestMapping(method = RequestMethod.GET)
    @ResponseBody
    public ResponseEntity<String> readAllLectures() throws IOException {
        List<LectureEntity> lectures = service.readAllLectures();
        List<LectureVO> lectureVOs = new ArrayList<>();
        if (lectures == null) {
            return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
        }
        for (LectureEntity lecture : lectures) {
            LectureVO lectureVO = new LectureVO();
            lectureVO.setId(lecture.getId());
            lectureVO.setName(lecture.getName());
            lectureVO.setStudents(lecture.getStudents());
            lectureVOs.add(lectureVO);
        }
        return new ResponseEntity<>(mapper.writeValueAsString(lectureVOs), HttpStatus.OK);
    }

    @RequestMapping(value = "/{lectureId}", method = RequestMethod.GET)
    public ResponseEntity<String> readLecture(@PathVariable("lectureId") Long lectureId) throws IOException {
        if (lectureId == null) {
            logger.error("lecture id can't be empty");
            return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
        }
        LectureVO lectureVO = new LectureVO();
        LectureEntity lecture = service.readLecture(lectureId);
        lectureVO.setId(lecture.getId());
        lectureVO.setName(lecture.getName());
        lectureVO.setStudents(lecture.getStudents());
        return new ResponseEntity<>(mapper.writeValueAsString(lectureVO), HttpStatus.OK);
    }

    @ExceptionHandler(value = RuntimeException.class)
    public void handleExceptions(RuntimeException rte, HttpServletResponse response, HttpServletRequest request) throws IOException {

        System.out.println(IOUtils.toString(request.getInputStream()));
        if (response == null) {
            logger.error(rte.getMessage(), rte);
            return;
        }
        if (rte == null) {
            logger.error("unknown exception");
            response.sendError(HttpStatus.INTERNAL_SERVER_ERROR.value());
            return;
        }
        logger.error(rte.getMessage(), rte);
        response.sendError(HttpStatus.INTERNAL_SERVER_ERROR.value());
    }
}
